package com.teichmann.core.targets.online.revolution;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.Tag;
import org.htmlparser.lexer.Lexer;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.NodeVisitor;

import com.teichmann.bo.Car;
import com.teichmann.bo.Seller;
import com.teichmann.core.annotations.Url;
import com.teichmann.core.util.ConnectionUtils;
import com.teichmann.core.util.CrawlerUtils;

@Url(value = "http://www.autocarro.com.br/autobusca.php")
public class AutoCarro extends BasicPage implements Serializable {

	private final String URL = this.getClass().getAnnotation(Url.class).value();
	private ArrayList<Car> cars = new ArrayList<Car>();
	private transient NodeVisitor visitor = new NodeVisitor() {
		
		@Override
		public void visitTag(Tag tag) {
			String name = tag.getTagName();
			if ("tr".equalsIgnoreCase(name)
					&& (tag.getAttribute("bgcolor") != null 
							&& (tag.getAttribute("bgcolor").contains("#c0c0c0".toUpperCase()) 
									|| tag.getAttribute("bgcolor").contains("#FFFFFF"))
									&& tag.getAttribute("HEIGHT").equals("30"))) {
				
				cars.add(extractInformation(tag));
			}
		}
	};

	public void performSearch(String parameter) throws IOException {

		parameter = parameter.replaceAll(" ", "%20");

		Map<String, String> parameters = new HashMap<String, String>();
		parameters.put("AutModelo", parameter);
		parameters.put("Tipo", "REV");

		String responseBody = ConnectionUtils.post(URL, parameters);

		int numberOfPages = org.apache.commons.lang.StringUtils.countMatches(responseBody,
				"autobusca.php?pagina");

		if (numberOfPages == 0) {
			if (org.apache.commons.lang.StringUtils.countMatches(responseBody,
					"autobuscaDet.php?") > 0)
				numberOfPages = 1;
		}

		List<String> urls = new ArrayList<String>();
		for (int x = 0; x < numberOfPages; x++) {
			responseBody = ConnectionUtils.get(URL + "?pagina=" + x + "&Tipo=REV&AutModelo="
					+ parameter);
			urls.add(responseBody);
		}

		setUrls(urls);

	}

	/**
	 * @param line
	 * @return
	 * 
	 * Default line for Autobello's site is
	 * <tr class="txt" style="cursor: pointer;" onclick="javascript: abrirVeiculo('449');">
	 * <td class="txt" height="20">AUDI</td>
	 * <td class="txt">A6 2.8</td>
	 * <td class="txt">1995</td>
	 * <td class="txt">1995</td>
	 * <td class="txt">BZM0202</td>
	 * <td class="txt">VERMELHA</td>
	 * <td class="txt">22.500,00</td>
	 * <td class="txt"><img src="../imagens/sistema/maquina.gif"></td>
	 * </tr>
	 * 
	 */
	public Car extractInformation(Tag line) {
		Car car = new Car();
		int count = 1;
		try {

			NodeList details = line.getChildren();
			details = details.extractAllNodesThatMatch(new NodeFilter() {
				public boolean accept(Node arg0) {
					if (arg0 instanceof TableColumn) {
						return true;

					}

					return false;
				}

			});

			Pattern intOnly = Pattern.compile("\\d*");

			car.setModelo(CrawlerUtils.removeUnusedFields(details.elementAt(0).getChildren()
					.elementAt(1).getChildren().elementAt(0).getText()));
			car.setPlaca(CrawlerUtils.removeUnusedFields(details.elementAt(1).getChildren()
					.elementAt(1).getChildren().elementAt(0).getText()));

			// ano fabricacao
			String anoModelo = CrawlerUtils.removeUnusedFields(details.elementAt(2)
					.getChildren().elementAt(1).getChildren().elementAt(0).getText());
			Matcher matcher = intOnly.matcher(anoModelo);
			try{
				if (matcher.find()) {
					car.setAnoModelo(new Integer(matcher.group()));
				} else {
					car.setAnoModelo(new Integer(anoModelo));
				}
			}
			catch (NumberFormatException e) {
			}
			
			car.setCor(CrawlerUtils.removeUnusedFields(details.elementAt(3).getChildren()
					.elementAt(1).getChildren().elementAt(0).getText()));
			car.setCombustivel(CrawlerUtils.removeUnusedFields(details.elementAt(4)
					.getChildren().elementAt(1).getChildren().elementAt(0).getText()));
			car.setValor(CrawlerUtils.removeUnusedFields(details.elementAt(6).getChildren()
					.elementAt(1).getChildren().elementAt(0).getText()));
			car.setUrl("http://www.autocarro.com.br/"
					+ ((LinkTag) details.elementAt(0).getChildren().elementAt(1)).getLink());
			car.setRevenda(new Seller(this.getClass().getSimpleName()));

		} catch (Exception e) {
			e.printStackTrace();
		}

		return car;

	}
	
	public List<Car> extractInformation() throws IOException {

		for (String code : getUrls()) {

			Parser parser = new Parser(new Lexer(code));
			try {
				parser.visitAllNodesWith(visitor);
			} catch (ParserException e) {
				e.printStackTrace();
			}
		}
		return cars;

	}

}
